﻿//==============================================================================  
//Copyright (C) 2012-2015 9UN.ORG. All rights reserved. 
//GUID：b2096c56-e0c2-490e-bbba-2242446de6cc
//CLR Version: 4.0.30319.18033
//Code Author：Kevin Wang
//Contact：Email(Admin@9un.org),QQ(265382 or 74344)
//Filename：MatchContentType
//Namespace：RuanRang.Core.Utility
//Functions：MatchContentType  
//Created by Kevin Wang at 2013/2/4 20:33:26 http://blog.9un.org
//============================================================================== 

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace RuanRang.Core.Utility
{
    public class GlobalMouseHandler :IDisposable
    {
        private readonly Timer _mouseTimer;
        /// <summary>
        /// Delegate MouseMoveHander
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The <see cref="MouseEventArgs" /> instance containing the event data.</param>
        public delegate void MouseMoveHander(object sender, MouseEventArgs args);
        /// <summary>
        /// Occurs when [mouse move event].
        /// </summary>
        public event MouseMoveHander MouseMoveEvent;
        /// <summary>
        /// Occurs when [mouse move to hot rectangle].
        /// </summary>
        public event MouseMoveHander MouseMoveToHotRectangleEvent;
        /// <summary>
        /// Occurs when [mouse leave from hot rectangle event].
        /// </summary>
        public event MouseMoveHander MouseLeaveFromHotRectangleEvent;

        /// <summary>
        /// Raises the <see>
        ///                <cref>E:MouseLeaveFromHotRectangleEvent</cref>
        ///            </see>
        ///     event.
        /// </summary>
        /// <param name="args">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
        public void OnMouseLeaveFromHotRectangleEvent(MouseEventArgs args)
        {
            var handler = MouseLeaveFromHotRectangleEvent;
            if (handler != null) handler(this, args);
        }

        /// <summary>
        /// Occurs when [mouse stopped event].
        /// </summary>
        public event MouseMoveHander MouseStoppedEvent;

        /// <summary>
        /// Raises the <see>
        ///                <cref>E:MouseStoppedEvent</cref>
        ///            </see>
        ///     event.
        /// </summary>
        /// <param name="args">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
        public void OnMouseStoppedEvent(MouseEventArgs args)
        {
            var handler = MouseStoppedEvent;
            if (handler != null) handler(this, args);
        }

        /// <summary>
        /// Raises the <see>
        ///              <cref>E:MouseMoveToHotRectangle</cref>
        ///            </see>  event.
        /// </summary>
        /// <param name="args">The <see cref="MouseEventArgs" /> instance containing the event data.</param>
        public void OnMouseMoveToHotRectangle(MouseEventArgs args)
        {
            var handler = MouseMoveToHotRectangleEvent;
            if (handler != null) handler(this, args);
        }

        /// <summary>
        /// Raises the <see>
        ///              <cref>E:MouseMoveEvent</cref>
        ///            </see>  event.
        /// </summary>
        /// <param name="args">The <see cref="MouseEventArgs" /> instance containing the event data.</param>
        public void OnMouseMoveEvent(MouseEventArgs args)
        {
            var handler = MouseMoveEvent;
            if (handler != null) handler(this, args);
        }

        /// <summary>
        /// Gets or sets the M point.
        /// </summary>
        /// <value>The M point.</value>
        private Point _mPoint;

        private Point _tempPoint;
        /// <summary>
        /// Gets the hot rectangle.
        /// </summary>
        /// <value>The hot rectangle.</value>
        public Rectangle HotRectangle { get; set; }

        /// <summary>
        /// Gets or sets the mouse handler interval.
        /// </summary>
        /// <value>The mouse handler interval.</value>
        public int MouseHandlerInterval { get; set; }

        /// <summary>
        /// Gets or sets the mouse stopped interval time.
        /// </summary>
        /// <value>The mouse stopped interval time.</value>
        public int MouseStoppedIntervalTime { get; set; }
        /// <summary>
        /// Initializes a new instance of the <see cref="GlobalMouseHandler" /> class.
        /// </summary>
        public GlobalMouseHandler()
        {
            _mPoint = new Point(-100, -100); //定义存放获取坐标的point变量 
            _tempPoint = new Point(-200, -200);
            HotRectangle = new Rectangle(-100, -100, 0x00, 0x00);
            MouseHandlerInterval = 100;
            MouseStoppedIntervalTime = 3;//default time;
            _mouseTimer = new Timer { Interval = MouseHandlerInterval };
            _mouseTimer.Tick += MouseTimerTick;
            _mouseTimer.Start();
        }

        private int _timerCount;
        /// <summary>
        /// Shows the cursor.
        /// </summary>
        /// <param name="status">The status.</param>
        [DllImport("user32.dll", EntryPoint = "ShowCursor", CharSet = CharSet.Auto)]
        public extern static void ShowCursor(int status);

        /// <summary>   
        /// 设置鼠标的坐标   
        /// </summary>   
        /// <param name="x">横坐标</param>   
        /// <param name="y">纵坐标</param>   
        [DllImport("User32")]
        public extern static void SetCursorPos(int x, int y);

        /// <summary>   
        /// 获取鼠标的坐标   
        /// </summary>   
        /// <param name="lpPoint">传址参数，坐标point类型</param>   
        /// <returns>获取成功返回真</returns>   
        [DllImport("User32")]
        public extern static bool GetCursorPos(ref Point lpPoint);

        /// <summary>
        /// Mouses the timer tick.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        private void MouseTimerTick(object sender, EventArgs e)
        {
            GetCursorPos(ref _mPoint);
            if (_mPoint != _tempPoint)
            {
                _timerCount = 0;
                var mArgs = new MouseEventArgs(MouseButtons.None, 0, _mPoint.X, _mPoint.Y, 0);
                OnMouseMoveEvent(mArgs);
                var y1 = HotRectangle.Height + HotRectangle.Y;
                var x1 = HotRectangle.Width + HotRectangle.X;
                if (_mPoint.Y <= y1 && _mPoint.Y >= HotRectangle.Y && _mPoint.X <= x1 && _mPoint.X >= HotRectangle.X)
                {
                    OnMouseMoveToHotRectangle(mArgs);
                }
                else
                {
                    OnMouseLeaveFromHotRectangleEvent(mArgs);
                }
            }
            else
            {
                _timerCount ++;
                if (_timerCount == MouseStoppedIntervalTime * 10)
                {
                    var mArgs = new MouseEventArgs(MouseButtons.None, 0, _mPoint.X, _mPoint.Y, 0);
                    OnMouseStoppedEvent(mArgs);
                    _timerCount = 0;
                }
            }
            _tempPoint = _mPoint;
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            _mouseTimer.Stop();
            _mouseTimer.Dispose();
        }
    }
}
